package com.create.myworld.objects.derive.substance;

import com.create.myworld.annotations.NotDo;
import com.create.myworld.enums.Sex;
import com.create.myworld.action.Action;
import com.create.myworld.living.people.AncestorPeople;
import com.create.myworld.objects.Substance;
import com.create.myworld.sse.NormalSSE;
import com.create.myworld.util.RabbitMQUtil;
import com.create.myworld.util.TimeUtil;
import com.create.myworld.values.Surname;
import com.create.myworld.worldthings.WorldThings;
import lombok.SneakyThrows;
import org.springframework.scheduling.annotation.Async;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;

/**
 * @author zcw
 * 生物基类
 */
public class Living extends Substance implements Action {

    /**
     * 种族
     */
    protected Class myself;

    /**
     * 父亲
     */
    protected Living father;

    /**
     * 母亲
     */
    protected Living mother;

    /**
     * 配偶
     */
    protected Living mate;

    /**
     * 后代
     */
    protected List<Living> children = new ArrayList();

    /**
     * 寿命(s)
     */
    protected Long liveTime;

    /**
     * 性别
     */
    protected Sex sex;

    /**
     * 年龄
     */
    protected Long year;

    /**
     * 名词:男朋友/女朋友
     */
    protected String maleName;

    /**
     * 姓氏
     */
    protected String surname;

    /**
     * 名称
     */
    protected String fullName;

    /**
     * 状态(1:空闲 2:繁忙)
     */
    public int status;

    /**
     * 设置继父
     */
    private void setStepFather(Living living) {
        this.father = living;
        RabbitMQUtil.pushNormal(getName() + "的继父:" + living.getName());
    }

    /**
     * 设置继母
     */
    private void setStepMother(Living living) {
        this.mother = living;
        RabbitMQUtil.pushNormal(getName() + "的继母:" + living.getName());
    }

    public Class getMyself() {
        return myself;
    }

    public Living getFather() {
        return father;
    }

    public Living getMother() {
        return mother;
    }

    public Living getMate() {
        return mate;
    }

    public List<Living> getChildren() {
        return children;
    }

    public Long getLiveTime() {
        return liveTime;
    }

    public Sex getSex() {
        return sex;
    }

    public String getMaleName() {
        return maleName;
    }

    public String getSurname() {
        return surname;
    }

    public String getFullName() {
        return fullName;
    }

    public Living() {

    }

    /**
     * 诞生
     *
     * @param sex
     * @param name
     * @param liveTime
     */
    protected Living(Class myself, Sex sex, String surname, String name, Long liveTime) {
        setName(surname + name);
        NormalSSE.contentList.add("开始创造" + getName());
        this.sex = sex;
        this.surname = surname;
        this.fullName = name;
        this.liveTime = liveTime;
        this.myself = myself;
        this.father = new Living();
        this.mother = new Living();
        this.maleName = this.sex.getSex().equals(Sex.Male.getSex()) ? "女朋友" : "男朋友";
        NormalSSE.contentList.add(getName() + "创造完成");
    }


    /**
     * 死亡
     */
    @SneakyThrows
    @Async(value = "taskExecutor")
    @NotDo
    public void die() {
        RabbitMQUtil.pushDie("ID为" + getId() + "的" + getName() + "死亡了,生存时间" + liveTime + "秒");
        /**
         * 通知父母/配偶/后代自己死亡
         */
        if (null != this.father) {
            this.father.receiveDie(this);
        }
        if (null != this.mother) {
            this.mother.receiveDie(this);
        }
        if (null != this.mate) {
            this.mate.receiveDie(this);
        }
        for (int i = 0; i < children.size(); i++) {
            Living child = children.get(i);
            if (i == 0) {
                if (myself.getName().equals(AncestorPeople.class.getName())) {
                    AncestorPeople me = (AncestorPeople) this;
                    AncestorPeople firstChild = (AncestorPeople) child;
                    firstChild.extend(me);
                }
            }
            child.receiveDie(this);
        }
    }

    /**
     * 接收父母/配偶/后代死亡通知
     *
     * @param living
     */
    private void receiveDie(Living living) {
        if (living == this.mate) {
            RabbitMQUtil.pushNormal(getName() + "痛失配偶:" + living.getName());
            this.mate = null;
            return;
        }
        if (living == this.father) {
            RabbitMQUtil.pushNormal(getName() + "痛失父亲:" + living.getName());
            this.father = null;
            return;
        }
        if (living == this.mother) {
            RabbitMQUtil.pushNormal(getName() + "痛失母亲:" + living.getName());
            this.mother = null;
            return;
        }
        if (this.children.contains(living)) {
            RabbitMQUtil.pushNormal(getName() + "白发人送黑发人,痛失爱子" + living.getName());
            this.children.remove(living);
            return;
        }
    }

    @NotDo
    public Long getYear() {
        return TimeUtil.getSeconds() - getStartTime();
    }

    @Override
    public void eat() {
        RabbitMQUtil.pushNormal(getName() + "在吃东西");
    }

    @Override
    public void drink() {
        RabbitMQUtil.pushNormal(getName() + "在喝东西");
    }

    @Override
    public void drain() {
        RabbitMQUtil.pushNormal(getName() + "在排泄");
    }

    @Override
    public void sleep() {
        RabbitMQUtil.pushNormal(getName() + "在睡觉");
    }

    @SneakyThrows
    @Override
    public void breed() {
        if (mate == null) {
            RabbitMQUtil.pushNormal(getName() + "没有" + maleName + ",无法交配,去找个" + maleName);
            love();
            return;
        }
        if (mate.status == 2) {
            RabbitMQUtil.pushNormal(getName() + "想交配,可是" + maleName + mate.getName() + "正在繁忙中,无法交配");
            return;
        }
        RabbitMQUtil.pushNormal(getName() + "在和" + mate.getName() + "交配");
        Living kids = (Living) myself.newInstance();
        kids.mate = null;
        kids.myself = this.myself;
        kids.father = (this.sex.getSex().equals(Sex.Male.getSex()) ? this : mate);
        kids.mother = (this.sex.getSex().equals(Sex.Female.getSex()) ? this : mate);
        kids.liveTime = ((long) (Math.random() * (liveTime + mate.liveTime)) + 1);
        kids.sex = (new Random().nextInt(2) == 1 ? Sex.Male : Sex.Female);
        kids.maleName = (kids.sex.getSex().equals(Sex.Male.getSex()) ? "女朋友" : "男朋友");
        String[] kidsName = this.sex.getSex().equals(Sex.Male.getSex()) ? Surname.getMaleName(surname, kids.sex) : Surname.getMaleName(mate.surname, kids.sex);
        kids.surname = kidsName[0];
        kids.fullName = kidsName[1];
        kids.name = kidsName[0] + kidsName[1];
        kids.id = UUID.randomUUID().toString().replace("-", "").toLowerCase();
        kids.startTime = TimeUtil.getSeconds();
        RabbitMQUtil.pushNormal(getName() + "和" + mate.getName() + "交配生出了" + kids.getName());
        WorldThings.insertLiving(kids);
        /**
         * 注入后代
         */
        this.children.add(kids);
        this.mate.children.add(kids);
    }

    @Override
    public void love() {
        if (mate != null) {
            RabbitMQUtil.pushNormal(getName() + "已经有" + maleName + "了,不能出轨");
            return;
        }
        Living living = WorldThings.getSameClassLiving(myself, sex);
        if (living == null) {
            RabbitMQUtil.pushNormal("其他人都有配偶了," + getName() + "找不到" + maleName);
            return;
        }
        mate = living;
        living.mate = this;
        RabbitMQUtil.pushNormal(getName() + "和" + living.getName() + "喜结连理,百年好合!");
        /**
         * 注入继父/继母
         */
        for (Living child : children) {
            if (sex.getSex().equals(Sex.Male.getSex())) {
                child.setStepMother(mate);
            } else {
                child.setStepFather(mate);
            }
        }
    }

    @Override
    public void talk() {
        RabbitMQUtil.pushNormal(getName() + "在交流");
    }

    /**
     * 自我介绍
     */
    @NotDo
    public void introduce() {
        if (RabbitMQUtil.rabbitTemplate != null) {
            RabbitMQUtil.pushNormal("***姓名:" + this.name + "***");
            RabbitMQUtil.pushNormal("***种族:" + this.myself + "***");
            RabbitMQUtil.pushNormal("***性别:" + this.sex.getSex() + "***");
            RabbitMQUtil.pushNormal("***年龄:" + this.getYear() + "***");
            RabbitMQUtil.pushNormal("***寿命:" + this.liveTime + "秒***");
            RabbitMQUtil.pushNormal("***父亲:" + (this.father == null ? "无" : this.father.getName()) + "***");
            RabbitMQUtil.pushNormal("***母亲:" + (this.mother == null ? "无" : this.mother.getName()) + "***");
            RabbitMQUtil.pushNormal("***配偶:" + (this.mate == null ? "无" : this.mate.getName()) + "***");
        }
    }

}
